class FusionGatlingFire extends TFProjectileFire;


var() float MaxRollSpeed;
var() float RollSpeed;
var() float BarrelRotationsPerSec;
var() int   RoundsPerRotation;
var() float FireTime;
var() Sound WindingSound, WindDownSound;
var() Sound FiringSound;
var TFFusionGatling Gun;
var() float WindUpTime;

var() String FiringForce;
var() String WindingForce;

var() byte MaxPitch;
var() float ProjFired, FiringSpeed;

function StartBerserk()
{
    ProjPerFire=Default.ProjPerFire+1;
    Spread=Default.Spread+400;
    maxPitch=Default.maxPitch+14;
}

function StopBerserk()
{
    ProjPerFire=Default.ProjPerFire;
    Spread=Default.Spread;
    maxPitch=Default.maxPitch;
}

function PostBeginPlay()
{
	Super.PostBeginPlay();
	FireRate = 0.15f / (RoundsPerRotation * BarrelRotationsPerSec);
	MaxRollSpeed = 65536.f*BarrelRotationsPerSec;
	Gun = TFFusionGatling(Owner);
}


function FlashMuzzleFlash()
{
	local rotator r;

	r.Roll = Rand(65536);
	Weapon.SetBoneRotation('Bone_Flash', r, 0, 1.f);
	Super.FlashMuzzleFlash();
}

event ModeDoFire()
{
    ProjFired += 16;
    if (ProjFired >= 400) ProjFired = 400;
    Recoil();
    Super.ModeDoFire();
}

function InitEffects()
{
	Super.InitEffects();

	if ( FlashEmitter != None )
	{
		FlashEmitter.SetDrawScale(2);
		Weapon.AttachToBone(FlashEmitter, 'Bone_Flash');
	}
}

function PlayAmbientSound(Sound AmbSound)
{
    if ( (TFFusionGatling(Weapon) == None) || (Instigator == None) || (AmbSound == None && ThisModeNum != Gun.CurrentMode) )
        return;

    Instigator.AmbientSound = AmbSound;
    Gun.CurrentMode = ThisModeNum;
}

function StopRolling()
{
    if (Gun == None || ThisModeNum != Gun.CurrentMode)
        return;

    RollSpeed = 0.f;
    Gun.RollSpeed = 0.f;
}

function PlayPreFire() {}
function PlayStartHold() {}

function PlayFiring()
{
	Weapon.PlayOwnedSound(FireSound,SLOT_Interact,TransientSoundVolume,,,Default.FireAnimRate/FireAnimRate,false);
}

function PlayFireEnd() {}
function StartFiring();
function StopFiring();
function bool IsIdle()
{
	return false;
}

auto state Idle
{
	function bool IsIdle()
	{
		return true;
	}

	function BeginState()
	{
		if (Instigator != None)
		{
			Instigator.GroundSpeed = Instigator.default.GroundSpeed;
			Instigator.SoundPitch = Instigator.default.SoundPitch;
			Instigator.SoundVolume = Instigator.default.SoundVolume;
		}
		PlayAmbientSound(None);
	//	StopRolling();
	}

	function EndState()
	{
		if (Instigator != None)
			Instigator.GroundSpeed = Instigator.default.GroundSpeed * 0.75;
		PlayAmbientSound(WindingSound);
	}

	function StartFiring()
	{
		RollSpeed = 0;
		FireTime = (RollSpeed/MaxRollSpeed) * WindUpTime;

		GotoState('WindUp');
	}
}

state WindUp
{
	function BeginState()
	{
		ClientPlayForceFeedback(WindingForce);  // jdf
	}

	function EndState()
	{
		if (ThisModeNum == 0)
		{
		//	if ( (Weapon == None) || !Weapon.GetFireMode(1).bIsFiring )
				StopForceFeedback(WindingForce);
		}
		else
		{
			if ( (Weapon == None) || !Weapon.GetFireMode(0).bIsFiring )
				StopForceFeedback(WindingForce);
		}
	}

	function ModeTick(float dt)
	{
		FireTime += dt;
		RollSpeed = (FireTime/WindUpTime) * MaxRollSpeed;
//		Instigator.SoundPitch = FireTime * MaxPitch;
		Instigator.SoundPitch = MaxPitch-(12-12*FireTime);
		Instigator.SoundVolume = FireTime * 255;

	//	NextFireTime = Level.TimeSeconds + 2*dt;

		if ( !bIsFiring )
		{
			GotoState('WindDown');
			return;
		}

		if (RollSpeed >= MaxRollSpeed)
		{
			Instigator.SoundVolume = 255;
			Instigator.SoundPitch = MaxPitch;
			RollSpeed = MaxRollSpeed;
			FireTime = WindUpTime;
			Gun.UpdateRoll(dt, RollSpeed, ThisModeNum);
			GotoState('FireLoop');
			return;
		}

		Gun.UpdateRoll(dt, RollSpeed, ThisModeNum);
	}

	function StopFiring()
	{
		GotoState('WindDown');
	}
}

state FireLoop
{
	function BeginState()
	{
		NextFireTime = Level.TimeSeconds + 0.15;
	//	PlayAmbientSound(FiringSound);
		ClientPlayForceFeedback(FiringForce);  // jdf
		ProjFired=0;
		if ( Weapon.HasAnim(FireLoopAnim) )
		{
			Weapon.PlayAnim(FireLoopAnim, FireLoopAnimRate, TweenTime);
		}
		else
		{
			Weapon.PlayAnim(FireAnim, FireAnimRate, TweenTime);
		}
	}

	function StopFiring()
	{
		GotoState('WindDown');
	}

	function EndState()
	{
	//	PlayAmbientSound(WindingSound);
		Instigator.GroundSpeed = Instigator.default.GroundSpeed * 0.75;
		StopForceFeedback(FiringForce);  // jdf
		Gun.LoopAnim(Gun.IdleAnim, Gun.IdleAnimRate, TweenTime);
	}

	function ModeTick(float dt)
	{
		Super.ModeTick(dt);

		Instigator.GroundSpeed = Instigator.default.GroundSpeed * 0.25;
	//	Instigator.SoundVolume = 255;
	//	Instigator.SoundPitch = MaxPitch;

		Gun.UpdateRoll(dt, RollSpeed, ThisModeNum);
		if ( !bIsFiring )
		{
			GotoState('WindDown');
			return;
		}
	}
}

state WindDown
{
	function BeginState()
	{
		ClientPlayForceFeedback(WindingForce);  // jdf
//		FusionGatling(Weapon).OutOfammo();
	}

	function EndState()
	{
		if (ThisModeNum == 0)
		{
			if ( (Weapon == None) || !Weapon.GetFireMode(1).bIsFiring )
			StopForceFeedback(WindingForce);
		}
		else
		{
			if ( (Weapon == None) || !Weapon.GetFireMode(0).bIsFiring )
			StopForceFeedback(WindingForce);
		}
	}

    function ModeTick(float dt)
	{
		if ( !TFFusionGatling(weapon).bStayWound )
			FireTime -= dt/2;
		RollSpeed = (FireTime/WindUpTime) * MaxRollSpeed;
//		Instigator.SoundPitch = FireTime * MaxPitch;
		Instigator.SoundPitch = MaxPitch-18/FireTime;
		Instigator.SoundVolume = FireTime * 255;

		if (RollSpeed <= 0.f)
		{
			Instigator.SoundVolume = 1;
			Instigator.SoundPitch = 1;
			RollSpeed = 0.f;
			FireTime = 0.f;
			Gun.UpdateRoll(dt, RollSpeed, ThisModeNum);
			GotoState('Idle');
			return;
		}

		Gun.UpdateRoll(dt, RollSpeed, ThisModeNum);
	}

	function StartFiring()
	{
		GotoState('WindUp');
	}

	function bool IsIdle()
	{
		return true;
	}
}

function Projectile SpawnProjectile(Vector Start, Rotator Dir)
{
    local FusionGatlingProj Proj;

    Proj = Spawn(class'FusionGatlingProj',,, Start+(int(20*Frand())*vector(Weapon.Rotation)), Dir);
    if ( Proj != None )
		Proj.Damage *= DamageAtten;

//    Recoil();
    return Proj;
}

function Recoil()
{
    local Rotator NewRotation;
    local float NewPitch, NewYaw;

    if ( (Instigator != None) && Instigator.IsFirstPerson()){
    NewPitch = int(Frand()*(450-ProjFired)); NewYaw = int(Frand()*(480-ProjFired));
    if (Frand() > 0.5) NewYaw *= -1;
    if (Frand() > 0.5) NewPitch *= -1;
    NewRotation = Instigator.GetViewRotation();
    NewRotation.Pitch += NewPitch;
    NewRotation.Yaw += NewYaw;
    Instigator.SetViewRotation(NewRotation);}
}

defaultproperties
{
     BarrelRotationsPerSec=2.000000
     RoundsPerRotation=3
     WindingSound=Sound'WeaponSounds.Minigun.miniempty'
     WindDownSound=Sound'WeaponSounds.BaseGunTech.BMiniGunWindDown'
     WindUpTime=2.000000
     FiringForce="minifireb"
     WindingForce="miniempty"
     maxPitch=68
     ProjPerFire=3
     ProjSpawnOffset=(Y=24.000000,Z=-12.000000)
     bPawnRapidFireAnim=True
     bModeExclusive=False
     PreFireTime=4.000000
     FireSound=Sound'WeaponSounds.BaseFiringSounds.BTranslocatorFire'
     AmmoClass=Class'Taskforces.FusionGatlingAmmo'
     AmmoPerFire=1
     ShakeRotMag=(X=50.000000,Y=50.000000,Z=50.000000)
     ShakeRotRate=(X=10000.000000,Y=10000.000000,Z=10000.000000)
     ShakeRotTime=2.000000
     ShakeOffsetMag=(X=1.000000,Y=1.000000,Z=1.000000)
     ShakeOffsetRate=(X=1000.000000,Y=1000.000000,Z=1000.000000)
     ShakeOffsetTime=2.000000
     ProjectileClass=Class'Taskforces.FusionGatlingProj'
     BotRefireRate=0.990000
     FlashEmitterClass=Class'XEffects.FlakMuzFlash1st'
     aimerror=300.000000
     Spread=300.000000
     SpreadStyle=SS_Random
}
